]> dgit.raspbian.org Git - gnome-shell.git/commitdiff
animation: Don't get size information until spinner has a parent
authorEvan Welsh <contact@evanwelsh.com>
Wed, 7 Jun 2023 15:47:50 +0000 (08:47 -0700)
committerMarge Bot <marge-bot@gnome.org>
Wed, 7 Jun 2023 18:59:43 +0000 (18:59 +0000)
get_size() in _syncAnimationSize() can't be called until the actor
has a parent, otherwise we'll get an error for calling
st_get_theme_node() prior to the actor being on a stage.

_syncAnimationSize() is called asynchronously via
textureCache.load_sliced_image() and there is currently no guarantee
the actor will actually be "loaded" prior to calling it.

This becomes a more obvious error/issue when refactoring parts of the
Shell loading to also be asynchronous.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/2563>

js/ui/animation.js

index c2ed248ef2de319979bb6a5e0ff78b94ef72db1f..b8d7f7beeb864b959a25134635c8626a30ad53a6 100644 (file)
@@ -36,6 +36,10 @@ class Animation extends St.Bin {
         this._frame = 0;
 
         this._loadFile(file, width, height);
+
+        // If the parent changes, we need to re-sync the animation
+        // size
+        this.connect('parent-set', () => this._syncAnimationSize());
     }
 
     play() {
@@ -72,8 +76,8 @@ class Animation extends St.Bin {
         let textureCache = St.TextureCache.get_default();
         let scaleFactor = St.ThemeContext.get_for_stage(global.stage).scale_factor;
         this._animations = textureCache.load_sliced_image(file, width, height,
-                                                          scaleFactor, resourceScale,
-                                                          this._animationsLoaded.bind(this));
+            scaleFactor, resourceScale,
+            () => this._syncAnimationSize());
         this._animations.set({
             x_align: Clutter.ActorAlign.CENTER,
             y_align: Clutter.ActorAlign.CENTER,
@@ -102,19 +106,16 @@ class Animation extends St.Bin {
     }
 
     _syncAnimationSize() {
-        if (!this._isLoaded)
+        this._isLoaded = this._animations.get_n_children() > 0;
+
+        // this.get_size() can't be called without a parent
+        if (!this._isLoaded || !this.get_parent())
             return;
 
         let [width, height] = this.get_size();
 
         for (let i = 0; i < this._animations.get_n_children(); ++i)
             this._animations.get_child_at_index(i).set_size(width, height);
-    }
-
-    _animationsLoaded() {
-        this._isLoaded = this._animations.get_n_children() > 0;
-
-        this._syncAnimationSize();
 
         if (this._isPlaying)
             this.play();